"""处理数据层，将前端的数据传入到本层进行处理，处理过程和结果将显示在控制台界面"""
import os
import re
import time
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from openpyxl import Workbook
from commonData import ComData as cd
"""
 我是一个可以偷走他人的梦，并且可以体验那个梦的人。
"""
class Data:

    def __init__(self):
        if cd.assign_state:  # 若用户指定了替代的excel文件
            print("因指定了处理站点，所以优先加载文件 {} ...".format(cd.assign_excel))
            wb = load_workbook(cd.assign_excel)
            ws = wb[wb.sheetnames[0]]
            for row in range(2, ws.max_row+1):
                row = str(row)
                dist_num = ws[cd.dist_num_index + row].value  # 区站号
                province = ws[cd.province_index + row].value  # 省份
                site_name = ws[cd.site_name_index + row].value  # 站名
                long = ws[cd.long_index + row].value    # 经度
                lat = ws[cd.lat_index + row].value  # 维度
                alt = ws[cd.alt_index + row].value  # 拔海高度
                cd.assign_excel_data[dist_num] = [dist_num, province, site_name, long, lat, alt]
            print("加载完毕..")

    def get_abnormal(fun):
        def abnormal(self, *args, **kwargs):
            try:
                return fun(self, *args, **kwargs)
            except Exception as e:
                print("异常信息:{},异常方法:{}".format(e, fun.__name__))

        return abnormal  # 没有返回值

    @get_abnormal
    def starDay(self):  # 处理Day文件数据，先假设所有数据都存在
        # 换一种数据存放的形式,Day数据一个文件夹内就可以进行处理
        # 月数据就需要12个月的数据
        month_day = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

        for name in os.listdir(cd.folder_in):
            file = cd.folder_in + "\\" + name
            print("正在处理: {}".format(file))
            year, month = re.findall(r'DAY(\d{4})(\d{2})', name)[0]
            month = int(month)
            if ((int(year) % 4 == 0 and int(year) % 100 != 0) or (int(year) % 400 == 0)):
                month_day[2] = 29  # 赋值为29日
            with open(file, "r", encoding='utf-8') as f:
                infos = f.readlines()
            elem = re.findall(r'elements=(.*)&', infos[0])[0].split(',')  # 第0个数据内，匹配所有的元素值
            dict_of_elements = {}
            number_of_elements = {}
            eon = {}  # elements_of_number
            i = 0
            for e in elem:
                dict_of_elements[e] = {}
                number_of_elements[i] = e
                eon[e] = i
                i += 1
            for info in infos[2:]:
                info = re.findall(r'[^\s]+', info)
                # print(info, len(info))
                """day中的 8 个基本信息"""
                id = info[eon['Station_Id_C']]  # 区站号
                station_name = info[eon['Station_Name']]  # 区站号名字
                lon = info[eon['Lon']]  # 经度
                lat = info[eon['Lat']]  # 维度
                alti = info[eon['Alti']]  # 海拔
                year = info[eon['Year']]
                mon = info[eon['Mon']]
                day = int(info[eon['Day']])  # 天数
                for e in cd.elements:  # 处理用户选择的字段名
                    if not cd.assign_state:
                        if e not in ['Station_Name', 'Station_Id_C', 'Lat', 'Lon', 'Alti', 'Year', 'Mon', 'Day']:  # 如果 id 不在内部，则表示为新的数据，那么需要重新开始添加数据
                            if id not in dict_of_elements[e]:
                                dict_of_elements[ e][id] = [id, station_name, lon, lat, alti, year, mon]
                                for no in range(month_day[month]):
                                    dict_of_elements[e][id].append('缺失')
                            dict_of_elements[e][id][day + cd.day_index - 2] = info[eon[e]]  # 对应信息的位置
                    else:
                        if e not in ['Station_Name', 'Station_Id_C', 'Lat', 'Lon', 'Alti', 'Year', 'Mon', 'Day']:
                            if id in cd.assign_excel_data:
                                if id not in dict_of_elements[e]:
                                    dict_of_elements[e][id] = cd.assign_excel_data[id] + [year, mon]
                                    for no in range(month_day[month]):
                                        dict_of_elements[e][id].append('缺失')
                                dict_of_elements[e][id][day + cd.day_index - 1] = info[eon[e]]  # 对应信息的位置


            if cd.assign_state:
                base = ['区站号', '省份', '站名', '经度', '纬度', '海拔', '年份', '月份']
            else:
                base = ['Station_Id_C', 'Station_Name',  'Lat', 'Lon', 'Alti', 'Year', 'Mon']

            for m in range(1, month_day[month] + 1):
                base += [str(m) + '日']
            wb = Workbook()
            ws = wb[wb.sheetnames[0]]
            wb.remove(ws)  # 移除掉新建excel表格式第一个默认的sheet1
            for sheet_name, infos in dict_of_elements.items():
                if len(infos) != 0:
                    # print(sheet_name)
                    ws = wb.create_sheet(sheet_name)  # 以气象因子建立新的表格
                    if cd.assign_state:   # 如果是用户指定的，因为多了一个数据，所以冻结的要向右移动一格
                        ws.freeze_panes = 'G2'
                    else:
                        ws.freeze_panes = 'F2'
                    ws.append(base)
                    for info in infos:
                        ws.append(infos[info])
            save_file = cd.folder_out + "\\" + name[:-4] + "_ok.xlsx"
            print("保存到%s" % save_file)
            wb.save(save_file)


    @get_abnormal
    def starMonth(self):  # 处理Month文件数据，先假设所有数据都存在
        years = set()
        for name in os.listdir(cd.folder_in):
            year = re.findall(r'MONTH(\d{4})', name)[0]
            years.add(year)
        # print(years)
        years = list(years)
        # time.sleep(12312)
        for year in years:
            dict_of_elements = {}
            number_of_elements = {}
            eon = {}  # elements_of_number
            for m in range(1, 12 + 1):
                month = '0' + str(m) if m < 10 else str(m)
                name = 'MONTH{year}{month}.txt'.format(year=year, month=month)
                file = cd.folder_in + "\\" + name
                if os.path.exists(file) == True:
                    print("正在处理：{}".format(file))
                    year, month = re.findall(r'MONTH(\d{4})(\d{2})', name)[0]
                    month = int(month)
                    with open(file, "r", encoding='utf-8') as f:
                        infos = f.readlines()
                    if len(eon) == 0:  # 每年的第一次处理的时候，将数据都重置为空
                        elem = re.findall(r'elements=(.*)&', infos[0])[0].split(',')  # 第0个数据内，匹配所有的元素值
                        i = 0
                        for e in elem:
                            dict_of_elements[e] = {}
                            number_of_elements[i] = e
                            eon[e] = i
                            i += 1
                    for info in infos[2:]:
                        info = re.findall(r'[^\s]+', info)
                        """day中的 8 个基本信息"""
                        id = info[eon['Station_Id_C']]  # 区站号
                        station_name = info[eon['Station_Name']]  # 区站号名字
                        lon = info[eon['Lon']]  # 经度
                        lat = info[eon['Lat']]  # 维度
                        alti = info[eon['Alti']]  # 海拔
                        year = info[eon['Year']]
                        for e in cd.elements:  # 处理用户选择的字段名
                            if not cd.assign_state:
                                if e not in ['Station_Name', 'Station_Id_C', 'Lat', 'Lon', 'Alti', 'Year', 'Mon','Day']:  # 如果 id 不在内部，则表示为新的数据，那么需要重新开始添加数据
                                    if id not in dict_of_elements[e]:
                                        dict_of_elements[e][id] = [id, station_name, lon, lat, alti, year]
                                        for no in range(1, 12 + 1):  # 12个月
                                            dict_of_elements[e][id].append('缺失')
                                    dict_of_elements[e][id][month + cd.month_index - 2] = info[eon[e]]  # 对应信息的位置
                            else:
                                if e not in ['Station_Name', 'Station_Id_C', 'Lat', 'Lon', 'Alti', 'Year', 'Mon','Day']:
                                    if id in cd.assign_excel_data:  # 若在内
                                        if id not in dict_of_elements[e]:
                                            dict_of_elements[e][id] = cd.assign_excel_data[id] + [year]
                                            for no in range(1, 12 + 1):  # 12个月
                                                dict_of_elements[e][id].append('缺失')
                                        dict_of_elements[e][id][month + cd.month_index - 1] = info[eon[e]]  # 对应信息的位置


                else:
                    print(file + "不存在!")
            if cd.assign_state:
                base = ['区站号', '省份', '站名', '经度', '纬度', '海拔', '年份']
            else:
                base = ['Station_Id_C', 'Station_Name',  'Lat', 'Lon', 'Alti', 'Year']
            for m in range(1, 12 + 1):  # 12个月
                base += [str(m) + '月']
            wb = Workbook()
            ws = wb[wb.sheetnames[0]]
            wb.remove(ws)  # 移除掉新建excel表格式第一个默认的sheet1
            for sheet_name, infos in dict_of_elements.items():
                if len(infos) != 0:
                    # print(sheet_name)
                    ws = wb.create_sheet(sheet_name)  # 以气象因子建立新的表格
                    if cd.assign_state:
                        ws.freeze_panes =  'G2'
                    else:
                        ws.freeze_panes = 'F2'
                    ws.append(base)
                    for info in infos:
                        ws.append(infos[info])
            save_file = cd.folder_out + "\\" + "MONTH{0}_ok.xlsx".format(year)
            print("保存到%s" % save_file)
            wb.save(save_file)


    # @get_abnormal
    def starExcel(self):
        """"根据用户指定的excel文件对已经处理好的excel文件进行处理"""
        # assign_excel_data 就是用户指定的用户数据

        for name in os.listdir(cd.folder_in):
            file = cd.folder_in + "\\" + name
            print("正在处理: %s " % file)
            new_file = cd.folder_out + "\\" + name  # 新的excel文件
            wb = load_workbook(file)
            exist_have = []    # 存在的，要摘取的数据位置。因为sheet都是一样的，所以这里先做处理，找出哪些位置是需要摘取的
            ws1 = wb[wb.sheetnames[0]]  # 从第一个sheet开始寻找数据，因为都一样，所以只需要第一个就ok
            for row in range(2, ws1.max_row + 1):
                station = ws1['A' + str(row)].value
                if station in cd.assign_excel_data.keys():  # 如果该区站号在用户所要提取的内
                    exist_have.append(row)   # 把所在行的位置加进去
            """提取数据"""
            new_data = {}
            head_data = []  # 表头数据
            for sheet_name in wb.sheetnames:
                ws = wb[sheet_name]
                new_data[sheet_name] = {}
                if len(head_data) == 0:
                    for data in ws["A{row}:{end}{row}".format(row=1, end=get_column_letter(ws.max_column))][0]:  # 获取原始文件的表头数据
                        head_data.append(data.value)
                    if 'Year' in head_data:
                        year_index = head_data.index('Year') + 1
                    elif '年份' in head_data:
                        year_index = head_data.index('年份') + 1
                    year_letter = get_column_letter(year_index)
                    if get_column_letter(year_index-1) < 'F':  # 若excle文件中的表头长度小于用户自定义的长度
                        head_data = ['区站号', '省份', '站名', '经度', '纬度', '海拔']  # 那么head就改为
                        for data in ws["{star}{row}:{end}{row}".format(row=1, star=year_letter, end=get_column_letter(ws.max_column))][0]:
                            head_data.append(data.value)

                for row in exist_have:
                    row = str(row)
                    station = ws['A' + row].value
                    import copy
                    new_data[sheet_name][station] = copy.deepcopy(cd.assign_excel_data[station])  # 获取一列数据
                    # print("Ws-Data: ", ws["{star}{row}:{end}{row}".format(row=row, star=year_letter, end=get_column_letter(ws.max_column))][0])
                    for data in ws["{star}{row}:{end}{row}".format(row=row, star=year_letter, end=get_column_letter(ws.max_column))][0]:
                        new_data[sheet_name][station].append(data.value)
            print("写入到文件中")
            """存储数据"""
            if '年份' in head_data:
                year_letter = get_column_letter(head_data.index('年份')+1)
            else:
                year_letter = get_column_letter(head_data.index('Year') + 1)
            wb = Workbook()
            ws = wb[wb.sheetnames[0]]
            wb.remove(ws)
            for sheet_name in new_data.keys():
                wb.create_sheet(sheet_name)
                ws = wb[sheet_name]
                ws.append(head_data)
                ws.freeze_panes = year_letter+'2'  # 冻结年份之后的数据
                for info in new_data[sheet_name].values():
                    ws.append(info)
            wb.save(new_file)
        print("处理完毕")






